package io.eyer.nio.core.event;

import io.eyer.nio.core.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by 青木 on 2015/8/17.
 */
public class ReactorPool {
    private static Logger logger = LoggerFactory.getLogger(ReactorPool.class);
    private Reactor[] reactors;
    private AtomicInteger index = new AtomicInteger(0);


    public ReactorPool(int readWriteEventHandlers) throws IOException {
        this.reactors = new Reactor[readWriteEventHandlers];
        for (int i = 0; i < this.reactors.length; i++) {
            this.reactors[i] = new Reactor();
            this.reactors[i].start();
        }
    }


    public void register(SocketChannel socketChannel) throws ClosedChannelException {
        getNextRWEventLoop().registeredChannel(socketChannel, SelectionKey.OP_READ);
    }

    public Reactor getNextRWEventLoop() {
        try {
            int i = this.index.getAndIncrement() % this.reactors.length;
            if (i < 0) {
                this.index.set(0);
                i = 0;
            }
            return this.reactors[i];
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return this.reactors[0];
        }
    }

    public void register(SocketChannel socketChannel, Session session) throws ClosedChannelException {
        getNextRWEventLoop().registeredSession(socketChannel, SelectionKey.OP_READ, session);
    }


    public void close() {
        for (Reactor reactor : this.reactors) {
            reactor.close();
        }
    }
}
